<?php

Raise::load('core.RaiseObject');
Raise::load('core.reflection.RaiseVariable');
Raise::load('db.core.RaiseDbConnection');

/**
 * RaiseDbSqlIdentifier class
 * identifies an table, column, or database name that must be escaped/enquoted
 * in the SQL code for safety reasons
 *
 * @author Sam-Mauris Yong / hellclanner at live dot com
 * @license http://www.opensource.org/licenses/bsd-license New BSD License
 * @package phpraise.db.sql
 * @since 1.2
 */
class RaiseDbSqlIdentifier extends RaiseObject {

    /**
     * The preceding identifier
     * @var RaiseDbSqlIdentifier
     */
    private $precedingIdentifier;

    /**
     * The identifier name
     * @var string
     */
    private $name;

    /**
     * The RaiseDbConnection assosciated with this RaiseDbSqlIdentifier object
     * @var RaiseDbConnection
     */
    private $connection;

    /**
     * Create and prepare a RaiseDbSqlIdentifier
     * @param string $n The name
     * @param RaiseDbConnection $c The connection
     */
    public function __construct($n, $c) {
        if(!RaiseVariable::isType($n, 'string') || trim($n) == ''){
            throw new RaiseInvalidArgumentException('RaiseDbSqlIdentifier::__construct() expecting $n to be a identifier. Empty string given instead.');
        }
        $this->name = $n;
        $this->connection($c);
    }
    
    /**
     * Get or set the preceding identifier
     * @param RaiseDbSqlIdentifier $p (optional) Set the new preceding identifier
     * @return RaiseDbSqlIdentifier
     */
    public function precedingIdentifier($p = null){
        if(func_num_args() == 1){
            $this->precedingIdentifier = $p;
        }
        return $this->precedingIdentifier;
    }

    /**
     * Get or set the connection to this adapter
     * @param RaiseDbConnection $c (optional) The new connection to set to
     * @return RaiseDbConnection
     */
    public function connection($c = null){
        if(func_num_args() == 1){
            if(!($c instanceof RaiseDbConnection)){
                throw new RaiseInvalidArgumentException('RaiseDbSqlIdentifier::connection() expecting parameter $c to an instance of RaiseDbConnection, ' . RaiseVariable::typeInfo($c) . ' given instead.');
            }
            $this->connection = $c;
        }
        return $this->connection;
    }

    /**
     * The name before escaping
     * @return string
     */
    public function name(){
        return $this->name;
    }
    
    /**
     * Create a full RaiseDbSqlIdentifier with table and field identifiers
     * @param string $field
     * @param RaiseDbConnection $conn
     * @return RaiseDbSqlIdentifier 
     * @static
     */
    public static function field($field, $conn){
        $id = new RaiseDbSqlIdentifier($field, $conn);
        return $id;
    }
    
    /**
     * Create a full RaiseDbSqlIdentifier with table and field identifiers
     * @param string $table
     * @param string $field
     * @param RaiseDbConnection $conn
     * @return RaiseDbSqlIdentifier 
     * @static
     */
    public static function tableField($table, $field, $conn){
        $id = new RaiseDbSqlIdentifier($field, $conn);
        $id->precedingIdentifier(new RaiseDbSqlIdentifier($table, $conn));
        return $id;
    }

    public function __toString(){
        $s = '';
        if($this->precedingIdentifier instanceof RaiseDbSqlIdentifier){
            $s = $this->precedingIdentifier->__toString() . '.';
        }
        return $s . $this->connection->adapter()->enquote($this->name);
    }

}